import json
import os
from typing import Dict, List, Any, Optional

class Config:
    def __init__(self, config_path: str = "config.json"):
        self.config_path = config_path
        self.default_config = {
            "request_settings": {
                "timeout": 30,
                "retry_times": 3,
                "delay_range": [1, 3],
                "user_agents": [
                    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
                    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
                    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
                ]
            },
            "proxy_settings": {
                "enabled": False,
                "proxy_list": [],
                "proxy_auth": None
            },
            "selenium_settings": {
                "driver": "chrome",
                "headless": True,
                "window_size": [1920, 1080],
                "page_load_timeout": 30
            },
            "storage_settings": {
                "default_format": "json",
                "output_dir": "output",
                "database": {
                    "type": "sqlite",
                    "connection_string": "sqlite:///crawler_data.db"
                }
            }
        }
        self.config = self.load_config()
    
    def load_config(self) -> Dict[str, Any]:
        if os.path.exists(self.config_path):
            try:
                with open(self.config_path, 'r', encoding='utf-8') as f:
                    user_config = json.load(f)
                    config = self.default_config.copy()
                    self._deep_update(config, user_config)
                    return config
            except (json.JSONDecodeError, FileNotFoundError):
                pass
        return self.default_config.copy()
    
    def save_config(self) -> None:
        os.makedirs(os.path.dirname(self.config_path) if os.path.dirname(self.config_path) else '.', exist_ok=True)
        with open(self.config_path, 'w', encoding='utf-8') as f:
            json.dump(self.config, f, indent=2, ensure_ascii=False)
    
    def _deep_update(self, base_dict: Dict, update_dict: Dict) -> None:
        for key, value in update_dict.items():
            if key in base_dict and isinstance(base_dict[key], dict) and isinstance(value, dict):
                self._deep_update(base_dict[key], value)
            else:
                base_dict[key] = value
    
    def get(self, key_path: str, default: Any = None) -> Any:
        keys = key_path.split('.')
        value = self.config
        try:
            for key in keys:
                value = value[key]
            return value
        except KeyError:
            return default
    
    def set(self, key_path: str, value: Any) -> None:
        keys = key_path.split('.')
        current = self.config
        for key in keys[:-1]:
            if key not in current:
                current[key] = {}
            current = current[key]
        current[keys[-1]] = value